Repository navigation
Add Gymnasium's 11 MuJoCo environments, played from pixels, with a Modal baseline job - #31
Open
r33drichards wants to merge 5 commits into
Open
r33drichards wants to merge 5 commits into
r33drichards wants to merge 5 commits into
Conversation
…ixels laya/mujocogames.py wraps Gymnasium's MuJoCo pendulums as laya.controlgames wraps classic control: ghosted screen from a fixed side view, one choice over named pushes (3 for the single pole, 5 for the double), seeded episodes, and expert (linear controller / LQR rounded to a push) and random baselines. ControlGame gains _make/_env_action hooks and play_episodes a make= argument so the subclass reuses rendering and scoring. The new games' goals and actions join CONTROL_GOALS / CONTROL_ACTIONS; existing questions are unchanged, so PROMPT_FORMAT_VERSION stays. examples/mujoco_video.py records an episode (expert, random or a checkpoint) to .webm/.mp4 with the chosen push and the model's probabilities. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH
…line script Reacher, Pusher, Swimmer, Hopper, Walker2d, HalfCheetah, Ant, Humanoid and HumanoidStandup join the pendulums in laya.mujocogames. They torque one joint at a time: NONE plus <JOINT>_POS / <JOINT>_NEG per actuated joint (laya.games.TORQUE_JOINTS), 5 to 35 options. The expert for seven of them is a lookahead planner that holds each push for a few steps in the simulator and restores it; on Pusher and Humanoid none beat doing nothing, so they have no expert. still_policy (always NONE) joins random as a baseline, and play_episodes reports solved_rate None for games without a threshold. examples/mujoco_baseline.py records a checkpoint's first episode per game to .webm and scores it against random, still and the expert on the same seeds; mujoco_video.py gains record() and a panel that fits 35 actions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH
play_mujoco runs laya.mujocogames.baseline for one game on an L4/A10G (OSMesa rendering, so nothing depends on the GPU driver's GL) and returns the model's first-episode .webm with the scores; mujoco_eval spawns all eleven and writes the videos and baseline.json locally. _load_policy_agent takes a Hub revision. draw / record / model_chooser / baseline / baseline_table move from the examples into laya.mujocogames so the Modal image (which ships laya/) can use them; the examples call them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH
The nine torque envs now set every joint each step: one `choice` per joint (laya.games.mujoco_questions) over STRONG_NEG / NEG / NONE / POS / STRONG_POS, all answered in one predict (the frame is encoded once). Mapping a strong expert's actions onto candidate spaces, one joint pushed per step kept at most 6% of its return on the walking robots and 8-128 presets at most 53%; five levels per joint kept 78-100%. It also fixes Humanoid's 35 options collapsing to 7 under the 256-token question budget (a test now checks every question keeps its options distinct). The experts are the Farama Foundation's SB3 policies on the Hub (mujocogames.HUB_EXPERTS, pinned by commit), rounded per joint; Pusher and Humanoid now have one. The one-joint lookahead planner is gone. Pendulums keep their single choice and scripted experts. ControlGame._env_action takes the action itself, play_episodes counts per-joint levels, and the video panel shows each joint's five levels. The Modal MuJoCo image gains stable-baselines3 and sb3-contrib. New questions only; existing games' input ids are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH
laya.mujocogames.expert_frames yields frames of the Hub expert's play, rendered exactly as in play, with one record per question asked about the frame: per joint, a soft target splitting its weight between the two levels nearest the expert's continuous action (soft_levels), label = argmax. The behaviour policy jitters each joint's level one notch with probability 0.1 (DART-style); uniformly random actions toppled the walkers and pendulums within 100-250 steps even at 5%. modal_app.py::prepare_mujoco writes /data/vqa/mujoco_<game> (refuses an existing name) with meta, manifest (expert repo and commit) and _READY; prepare_mujoco_all fans out one CPU container per game. MujocoGame._make imports torch._dynamo before gymnasium/mujoco: with MUJOCO_GL=osmesa, OSMesa's LLVM loaded first and triton's bundled LLVM (pulled in when an SB3 expert loads) then segfaulted the process. The Modal MuJoCo image sets PYTHONFAULTHANDLER=1 so a native crash prints a stack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
All eleven of Gymnasium's MuJoCo
-v5environments, played from the rendered screen with onechoiceper step. This works likelaya/controlgames.pydoes for classic control.laya/mujocogames.py:MujocoGamesubclassesControlGame, so it gets the same previous-frame ghosting, seeding and scoring. MuJoCo actions are continuous, so each game names a set of pushes:NONE, then<JOINT>_POS/<JOINT>_NEGfor each actuated joint. That is 5 options for Reacher up to 35 for Humanoid. Reacher and Pusher get closer cameras; the rest keep Gymnasium's tracking camera.random_policy, and a newstill_policy(alwaysNONE), on the same seeds.laya/controlgames.py: small hooks (SPECS,_make,_env_action,play_episodes(make=)), andsolved_rateisNonefor games without a threshold. Classic-control behaviour is unchanged.laya/games.py: goals and actions for the new games, generated fromTORQUE_JOINTS. Existing questions don't change, soPROMPT_FORMAT_VERSIONstays at"1".laya.mujocogames.recordwrites a real-time.webmwith the model's probabilities beside the screen, andbaselinescores a checkpoint on one game.examples/mujoco_video.pyandexamples/mujoco_baseline.pyrun them locally.modal_app.py::mujoco_eval: runs every game at once, one L4/A10G each (play_mujoco, rendering with OSMesa), and writes the videos andbaseline.jsonlocally._load_policy_agentnow accepts a Hubrevision.site-docs/how-to/play-games.md.This PR doesn't add the MuJoCo games to the games suite and publishes no numbers.
Known issue: Humanoid prompts don't fit the question budget
At the released checkpoint's
head_max_len=256, the 35 options of Humanoid and HumanoidStandup are cut to 5 tokens each, which leaves only 7 distinct option texts:ABDOMEN_Z_POS: torque the abdomen z one way (positive)becomes- ABDOMEN. Shorter wording can't fix it, because evenRIGHT_SHOULDER_1_POSalone is longer than 5 tokens. The fix is a smaller action set for these two games (for example grouped limb moves) or a larger budget. That decision is still open, so the Humanoid rows below are not valid.The other nine games keep every option distinct. Pusher (15 options), Walker2d and HalfCheetah (13 each) and Ant (17) lose part of each description, but no action names.
Zero-shot baseline (not a published number)
modal run modal_app.py::mujoco_eval --revision 8b318c99d7ad3ce19c24369263463882eada9d1e --max-steps 0:thaitea/laya-vision@8b318c9, 3 model episodes and 10 of each baseline from seed 200000, full-length episodes, about 26 minutes on Modal.⚠ These rows are invalid: see the known issue above.
On the nine valid games, the model beats random on 7 and never beats doing nothing. Normalizing against random flatters it: on the robots that only need to stay upright,
NONEis the stronger baseline. Ant's 0.75 is mostly survival, since the planner barely beats doing nothing there.Testing
tests/test_mujocogames.py(skipped unlessmujocoandgymnasiumare installed): for every game, pushes match the action names and action space, and a frame renders. Experts beat random and still. The lookahead leaves the episode unchanged. Pendulum experts hold the pole to the limit. Also covers seeding, ghosting, and the questions. 34 passed together withtests/test_controlgames.py.python -m pytest -qrun on the first commit gave 304 passed and 6tests/test_smolvlm2.pyImportErrors, which also fail onmainin this sandbox.mujoco_evalran end to end on Modal: a 2-game probe, then all 11 games.mkdocs build --strictpasses (pip MkDocs; nix isn't available in the sandbox).🤖 Generated with Claude Code
https://claude.ai/code/session_01X7wWfNMM9Rbk1757w3FaTH